using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

using SmartRename.Containers;
using SmartRename.Interfaces;

using SmartRename.Interfaces;
using System.Text.RegularExpressions;

namespace SmartRename
{
    public class SmartRename : ISmartRename
    {
        private Dictionary<string, IReplacement> _replacements;
        private Dictionary<string, IReplacement> Replacements
        {
            get
            {
                if (this._replacements == null)
                {
                    this._replacements = new Dictionary<string, IReplacement>(Program.ReplacementContainer.Replacements.Count);
                    foreach (IReplacement replacement in Program.ReplacementContainer.Replacements)
                    {
                        this._replacements.Add(replacement.EscapeKey, replacement);
                    }
                }
                return this._replacements;
            }
        }

        private string _renameFormat;
        public string RenameFormat
        {
            get { return _renameFormat; }
            set { _renameFormat = value; }
        }
        
        private List<RenameFile> _renameFiles;
        public List<RenameFile> RenameFiles
        {
            get { return _renameFiles; }
            set { _renameFiles = value; }
        }

        public SmartRename() { }        

        private string GetNewName(RenameFile file)
        {
            string newName = this.RenameFormat;
            foreach (KeyValuePair<string, IReplacement> replacement in this.Replacements)
            {
                newName = DoReplacement(file, newName, replacement, false);
                newName = DoReplacement(file, newName, replacement, true);
            }
            return newName;
        }

        private static string DoReplacement(RenameFile file, string newName, KeyValuePair<string, IReplacement> replacement, bool toUpper)
        {
            string escapeKey = toUpper ? replacement.Key.ToUpper() : replacement.Key;
            Regex key = new Regex(string.Format("{0}{1}|{0}", escapeKey , "{([0-9a-zA-Z:.]*)}"));
            MatchCollection matches = key.Matches(newName);
            foreach (Match match in matches)
            {
                string[] arguments = null;
                if (match.Groups.Count == 2)
                {
                    string argument = match.Groups[1].Value;
                    if (!string.IsNullOrEmpty(argument))
                    {
                        newName = newName.Replace(string.Format("{{{0}}}", argument), string.Empty);
                        arguments = argument.Split(':');
                    }
                }
                newName = newName.Replace(escapeKey, replacement.Value.GetReplacement(file, arguments, toUpper));
            }
            return newName;
        }

        public virtual void SetNewNames()
        {
            //if we have a valid format, update all the "new name" values":
            if (!string.IsNullOrEmpty(this.RenameFormat))
            {
                //reset the replacements to their seed values:
                Program.ReplacementContainer.Reset();
                foreach (RenameFile file in this.RenameFiles)
                {
                    file.NewName = this.GetNewName(file);
                }
            }
        }

        public virtual void CommitNewNames()
        {
            foreach (RenameFile file in this.RenameFiles)
            {
                if (file.Rename)
                {
                    file.TryRename();
                }
            }
        }
    }
}
